<?php

namespace App\Services;

use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;

class SystemConfigService
{
    protected string $cacheKey = 'system_config';

    public function getConfig(string $key, mixed $default = null)
    {
        $allConfig = $this->getAllConfig();
        $value = Collection::make($allConfig)
            ->where('name', $key)
            ->value('value');

        return $this->parseValue($value, $default);
    }

    public function getConfigByGroup(string $group): array
    {
        $allConfig = $this->getAllConfig();

        return Collection::make($allConfig)
            ->where('group_name', $group)
            ->map(function ($item) {
                return [$item->name => $this->parseValue($item->value)];
            })
            ->toArray();
    }

    public function getAllConfig(): array
    {
        return Cache::remember($this->cacheKey, 3600, function () {
            return \App\Models\SystemConfig::query()->select(['name', 'value', 'group_name'])->get()->toArray();
        });
    }

    public function deleteCache()
    {
        Cache::forget($this->cacheKey);
    }

    protected function parseValue(mixed $value, mixed $default = null): mixed
    {
        if (! $value) {
            return $default;
        }

        if (is_bool($value)) {
            return $value;
        }

        if (is_string($value)) {
            $lowerValue = strtolower($value);
            if ($lowerValue === 'true') {
                return true;
            }
            if ($lowerValue === 'false') {
                return false;
            }

            if (is_numeric($value)) {
                if (strpos($value, '.') === false) {
                    return (int) $value;
                }

                return (float) $value;
            }

            if (str_starts_with($value, '[') || str_starts_with($value, '{')) {
                $decoded = json_decode($value, true);
                if (json_last_error() === JSON_ERROR_NONE) {
                    return $decoded;
                }
            }

            return $value;
        }

        if (is_numeric($value)) {
            if (is_int($value) || (is_float($value) && floor($value) == $value)) {
                return (int) $value;
            }

            return (float) $value;
        }

        if (is_array($value)) {
            return $value;
        }

        return $value;
    }
}
